package demos;

import java.util.concurrent.*;

public class UsefulToolDemo {
    public static void main(String[] args) throws InterruptedException {
//        testCountDownLatch();
        testCyclicBarrier();
//        testSemaphore();
    }

    /**
     * 信号量的封装类
     */
    private static void testSemaphore() {
        Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t 抢占到位置");
                    // 抢占一段时间的位置
                    try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.println(Thread.currentThread().getName() + "\t 离开位置");
                    semaphore.release();
                }
            }, String.valueOf(i)).start();
        }
    }

    /**
     * 循环正计数
     * 计数达到parties值后，阻塞的线程才会继续工作
     * 接着重新正计数
     */
    private static void testCyclicBarrier() {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("******** end up *********");
        });
        for (int i = 0; i < 7; i++) {
            final int tempI = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 第" + tempI + "个线程");
                try {
                    System.out.println("### get number wait: " + cyclicBarrier.getNumberWaiting());
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
        for (int i = 0; i < 7; ++i) {
            new Thread(() -> {
                System.out.println("--- new round get wait:" + cyclicBarrier.getNumberWaiting());
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    /**
     * CountDownLatch倒计数，在计数为0之前，await处阻塞。
     * 计数器的值变为0后，因await阻塞的线程被唤醒。
     * @throws InterruptedException _
     */
    private static void testCountDownLatch() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " \t 离开");
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t 关门");
    }
}
